package com.shenhaofeng.app.loader.list.component;

import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import com.shenhaofeng.app.loader.list.Component;
import com.shenhaofeng.app.loader.list.DataSource;
import com.shenhaofeng.app.loader.list.Pager;
import com.shenhaofeng.app.loader.list.listener.OnBindDataListener;
import com.shenhaofeng.app.loader.list.listener.OnRefreshStatusListener;

import java.util.concurrent.Executor;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;


/**
 * Created by haofeng on 2016/9/28.
 */

public class RefreshComponent<D> extends Component<D> {

    private OnRefreshStatusListener<D> statusListener;


    public RefreshComponent(OnRefreshStatusListener<D> statusListener) {
        this.statusListener = statusListener;
    }


    public RefreshComponent(Executor mExecutor, OnRefreshStatusListener<D> statusListener) {
        super(mExecutor);
        this.statusListener = statusListener;
    }


    public RefreshComponent(Looper mLooper, OnRefreshStatusListener<D> statusListener) {
        super(mLooper);
        this.statusListener = statusListener;
    }


    @Override
    protected void attach(@NonNull ViewGroup mRefreshLayout, @NonNull ViewGroup mDataLayout, @NonNull DataSource<D> mDataSource, @NonNull OnBindDataListener<D> listener) {
        super.attach(mRefreshLayout, mDataLayout, mDataSource, listener);
        getSwipeRefreshLayout().setOnRefreshListener(new onRefreshListener());
    }


    protected SwipeRefreshLayout getSwipeRefreshLayout() {
        return (SwipeRefreshLayout) getRefreshView();
    }


    @Override
    protected boolean hasLoadView(ViewGroup mRefreshLayout, ViewGroup mDataLayout) {
        return mRefreshLayout instanceof SwipeRefreshLayout;
    }


    @Override
    protected void onRefresh(ViewGroup mRefreshLayout, ViewGroup mDataLayout, final int page, int pageSize, DataSource<D> dDataSource, OnBindDataListener<D> dataListener) {
        final SwipeRefreshLayout swipeRefreshLayout = getSwipeRefreshLayout();
        getDataSource().onRequestData(page, pageSize)
                .subscribeOn(getWorkScheduler())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<D>() {
                    @Override
                    public void onStart() {
                        swipeRefreshLayout.post(new Runnable() {
                            @Override
                            public void run() {
                                onRefreshStart(swipeRefreshLayout);
                            }
                        });
                    }


                    @Override
                    public void onCompleted() {
                        swipeRefreshLayout.post(new Runnable() {
                            @Override
                            public void run() {
                                getPageManager().reset();
                                onRefreshCompleted(swipeRefreshLayout);
                            }
                        });
                    }


                    @Override
                    public void onError(final Throwable e) {
                        swipeRefreshLayout.post(new Runnable() {
                            @Override
                            public void run() {
                                onRefreshThrowable(swipeRefreshLayout, e);
                            }
                        });
                    }


                    @Override
                    public void onNext(final D data) {
                        swipeRefreshLayout.post(new Runnable() {
                            @Override
                            public void run() {
                                onRefreshSuccess(swipeRefreshLayout, data);
                                getListener().onBindDataToAdapter(getDataView(), page, data);
                            }
                        });
                    }
                });
    }


    @Override
    protected void onMore(ViewGroup mRefreshLayout, ViewGroup mDataLayout, int page, int pageSize, DataSource<D> dDataSource, OnBindDataListener<D> dataListener) {

    }


    protected void onRefreshStart(SwipeRefreshLayout swipeRefreshLayout) {
        statusListener.onRefreshStart(swipeRefreshLayout);
    }


    protected void onRefreshCompleted(SwipeRefreshLayout swipeRefreshLayout) {
        statusListener.onRefreshCompleted(swipeRefreshLayout);
    }


    protected void onRefreshThrowable(SwipeRefreshLayout swipeRefreshLayout, Throwable e) {
        statusListener.onRefreshThrowable(swipeRefreshLayout, e);
    }


    protected void onRefreshSuccess(SwipeRefreshLayout swipeRefreshLayout, D data) {
        statusListener.onRefreshSuccess(swipeRefreshLayout, data);
    }


    protected class onRefreshListener implements SwipeRefreshLayout.OnRefreshListener {

        @Override
        public void onRefresh() {
            if (isAttached()) {
                Pager pager = getPageManager();
                int page = pager.getFirstPage();
                int pageSize = pager.getPageSize();
                RefreshComponent.this.onRefresh(getRefreshView(), getDataView(), page, pageSize, getDataSource(), getListener());
            } else {
                throw new IllegalStateException();
            }
        }
    }

}
